import { MuscleBodyfatAnalysis } from './Consts'
import { kg2lb, kg2st } from '@/utils/format/unit'
import { strip } from 'number-precision'

export const calcHeightMeter = (height: number): number => {
  return height / 100
}

/**
 * 计算标准体重
 * @param height number 以厘米为单位
 * @param gender number 性别 1 男 0 女
 */
export const calcSTDWeight = (height: number, gender: number): number => {
  const heightMeter = toFixedNumber(height / 100, 2)
  // BMI （男：22，女：21）
  const BMI = gender === 1 ? 22 : 21.5
  // 标准体重  STD Weight =  身高height x 身高height x BMI （男：22，女：21）
  return heightMeter * heightMeter * BMI
}

/**
 * 计算标准肌肉量
 */
export const calcSTDMuscleMass = (height: number, gender: number): number => {
  const calcSTDWeightValue = calcSTDWeight(height, gender)
  const STDWaterCalc = gender === 1 ? 0.62406 : 0.56705
  const STDProteinCalc = gender === 1 ? 0.16785 : 0.1526
  return calcSTDWeightValue * (STDProteinCalc + STDWaterCalc)
}

/**
 * 计算需要返回的值
 */
export const calcValues = (value: number | string, boundaries: Array<number | string>, max: number, min: number) => {
  let level = 1
  let indexProgress = 0
  let progress = 0
  const step = 1 / (boundaries.length + 1)
  if (value <= boundaries[0]) {
    level = 0
    if (value > min) {
      indexProgress = (Number(value) - min) / (Number(boundaries[0]) - min)
    }
  } else if (value > boundaries[1]) {
    level = 2
    if (value < max) {
      indexProgress = (Number(value) - Number(boundaries[1])) / (max - Number(boundaries[1]))
    } else {
      indexProgress = step
    }
  } else {
    indexProgress = (Number(value) - Number(boundaries[0])) / (Number(boundaries[1]) - Number(boundaries[0]))
  }
  indexProgress *= step
  progress = level * step + indexProgress
  indexProgress *= 100
  progress *= 100
  return { level, progress, indexProgress }
}

/**
 * 数值返回对应小数位数的数字
 */

export const toFixedNumber = (value: number, precision = 1): number => {
  value = Number(value)
  return Number(value.toFixed(precision))
}

/**
 * 四舍五入取两位小数
 * 判断第二位小数是否为零
 * 为零该指标则在界面上显示一位小数数值
 * 不为零则在界面上显示两位小数数值
 * input 1.33333333 outinput 1.33
 * input 1.30 outinput 1.3
 * input 1 outinput 1.0
 */
export const toFixedString = (value: number) => {
  // value = Number(value)
  let calcValue = value.toFixed(2)
  const reg = /\.\d0$/
  if (reg.test(calcValue)) {
    calcValue = calcValue.replace(/0$/, '')
  }
  return calcValue
}

/**
 * 计算范围平均值
 */
export const boundariesAverage = (boundaries: Array<number>) => {
  return boundaries.reduce((a, b) => Number(a) + Number(b)) / boundaries.length
}

export const muscleAnalysisData = (MuscleBodyfatAnalysisType: number) => {
  let analysis = ''
  let suggestion = ''
  let bodyTypeWeight = ''
  let bodyType = ''
  switch (MuscleBodyfatAnalysisType) {
    case MuscleBodyfatAnalysis.OVER_WEIGHT_WEAK:
      analysis = 'fat_analysis_1007'
      suggestion = 'fat_analysis_1008'
      bodyTypeWeight = 'fat_analysis_1002'
      bodyType = 'fat_analysis_1003'
      break
    case MuscleBodyfatAnalysis.OVER_WEIGHT_MUSCLE:
      analysis = 'fat_analysis_1010'
      suggestion = 'fat_analysis_1009'
      bodyTypeWeight = 'fat_analysis_1002'
      bodyType = 'fat_analysis_1006'
      break
    case MuscleBodyfatAnalysis.OVER_WEIGHT_FAT:
      analysis = 'fat_analysis_1012'
      suggestion = 'fat_analysis_1011'
      bodyTypeWeight = 'fat_analysis_1002'
      bodyType = 'fat_analysis_1004'
      break
    case MuscleBodyfatAnalysis.STANDARD_WEIGHT_WEAK:
      analysis = 'fat_analysis_1014'
      suggestion = 'fat_analysis_1013'
      bodyTypeWeight = 'fat_analysis_1027'
      bodyType = 'fat_analysis_1003'
      break
    case MuscleBodyfatAnalysis.STANDARD_WEIGHT_FAT:
      analysis = 'fat_analysis_1016'
      suggestion = 'fat_analysis_1015'
      bodyTypeWeight = 'fat_analysis_1027'
      bodyType = 'fat_analysis_1004'
      break
    case MuscleBodyfatAnalysis.STANDARD_WEIGHT_MUSCLE:
      analysis = 'fat_analysis_1018'
      suggestion = 'fat_analysis_1017'
      bodyTypeWeight = 'fat_analysis_1027'
      bodyType = 'fat_analysis_1006'
      break
    case MuscleBodyfatAnalysis.STANDARD_WEIGHT_HEALTH:
      analysis = 'fat_analysis_1020'
      suggestion = 'fat_analysis_1019'
      bodyTypeWeight = 'fat_analysis_1027'
      bodyType = 'fat_analysis_1005'
      break
    case MuscleBodyfatAnalysis.LOW_WEIGHT_WEAK:
      analysis = 'fat_analysis_1022'
      suggestion = 'fat_analysis_1021'
      bodyTypeWeight = 'fat_analysis_1028'
      bodyType = 'fat_analysis_1003'
      break
    case MuscleBodyfatAnalysis.LOW_WEIGHT_MUSCLE:
      analysis = 'fat_analysis_1024'
      suggestion = 'fat_analysis_1023'
      bodyTypeWeight = 'fat_analysis_1028'
      bodyType = 'fat_analysis_1006'
      break
  }
  return { analysis, suggestion, bodyTypeWeight, bodyType }
}

export function calcLevel(value: number, boundaries: Array<number>, standLevel: number) {
  let level = 0
  for (let i = 0; i < boundaries.length; i++) {
    if (+value < +boundaries[i] || (+value == +boundaries[i] && level == standLevel)) {
      break
    }
    level++
  }
  return level
}

const unitList = ['kg', 'lb', 'st']


/**
 * 根据现有单位，和系统单位，输出对应的值
 * 比如水分 22.3L 跟体重单位没关系 输出 22.3
 * 比如 体重 50.1kg 系统单位是斤 输出 100.2 系统单位是公斤或者kg 输出 50.1
 * @param valueUnit 值本身的单位
 * @param systemUnit 系统单位
 * @param value 值
 */
export function calcUnitValue(valueUnit: string, systemUnit: string, value: number | string, isFormat = false): number | string {
  value = parseFloat(value?.toString())
  if (!unitList.includes(valueUnit)) return value
  if (systemUnit === 'lb' && valueUnit === 'kg') {
    return kg2lb(value)
  } else if (systemUnit === 'st' && valueUnit === 'kg') {
    const kg2stValue = kg2st(value)
    let kg2stValueStr = kg2stValue[0] + ':' + kg2stValue[1].toFixed(1)
    if (isFormat) kg2stValueStr = kg2stValue[0] + 'st' + kg2stValue[1].toFixed(1) + 'lb'
    return kg2stValueStr
  }
  return number2Fixed(value)
}

/**
 * 单位转化
 * @param valueUnit 值本身的单位
 * @param systemUnit 系统的单位 kg st lb
 * @param isFormat 是否格式化，针对st
 * 
 * @example
 * kg => kg
 * lb => lb
 * l => l
 * st isFormat 为 true 返回空
 */
export const calcUnit = (valueUnit: string, systemUnit: string, isFormat = false) => {
  if (valueUnit === 'kg' && systemUnit === 'st') {
    if (isFormat) return ''
    return 'st:lb'
  } else if (valueUnit === 'kg' && systemUnit === 'lb') {
    return 'lb'
  } else if (valueUnit === 'kg' && systemUnit === 'st_only') {
    return 'st'
  }
  return valueUnit
}

export const generateUnitValueFn = (systemUnit: string, isFormat = false) => (valueUnit: string, value: number | string) => {
  value = parseFloat(value?.toString())
  value = +number2Fixed(value)
  if (systemUnit === 'lb' && valueUnit === 'kg') {
    value = kg2lb(value)
    valueUnit = 'lb'
  } else if (systemUnit === 'st' && valueUnit === 'kg') {
    const kg2stValue = kg2st(value)
    if (isFormat) {
      valueUnit = ''
      value = kg2stValue[0] + 'st' + kg2stValue[1].toFixed(1) + 'lb'
    } else {
      valueUnit = 'st:lb'
      value = kg2stValue[0] + ':' + kg2stValue[1].toFixed(1)
    }
  }
  else if (systemUnit === 'st_only') {
    value = strip((kg2lb(value) / 14), 2)
    valueUnit = 'st'
  }
  return {
    value,
    valueUnit
  }
}
export const newGenerateUnitValueFn = (systemUnit: string) => (valueUnit: string) => (value: number | string) => {
  value = parseFloat(value?.toString())
  value = +number2Fixed(value)
  // let valueArray: number[] = []
  if (systemUnit === 'lb' && valueUnit === 'kg') {
    value = kg2lb(value)
    // console.log('lb', value)
  } else if (systemUnit === 'st' && valueUnit === 'kg') {
    return kg2st(value)
  } else if (systemUnit === 'st_only' && valueUnit === 'kg') {
    value = strip((kg2lb(value) / 14).toFixed(2))
  }
  return value
}

export function number2Fixed(value: number) {
  let calcValue = value.toFixed(2)
  const reg = /\.\d0$/
  if (reg.test(calcValue)) {
    calcValue = calcValue.replace(/0$/, '')
  }
  return calcValue
}